﻿using EkStudio.com.bean.xml.BillModule;
using EkStudio.com.bean.xml.BillReflect;
using EkStudio.com.bean.xml.RootInterface.Plugin;
using EkStudio.com.ui.unitbill.property.factory;
using System;
using System.Reflection;

namespace EkStudio.com.ui.unitbill.property
{
    /// <summary>
    /// 反射字段属性配置
    /// </summary>
    public class BillReflectNodeToProperty : ObjectToProperty
    {
        private bool multiple = false;
        private BillRefectDataNode node = null;
        private BillReflectModuleItem bill = null;
        private BillReflectNodeToProperty[] list = null;

        private BillModuleItem target = null;

        private BillExpandJavaCodeItem java = null;

        public BillReflectNodeToProperty(BillRefectDataNode item,BillReflectModuleItem bean)
        {
            node = item;
            bill = bean;
        }

        public BillReflectNodeToProperty(BillReflectNodeToProperty[] lt, BillReflectModuleItem bean)
        {
            list = lt;
            multiple = true;
            bill = bean;
        }

        public string Caption
        {
            get { return multiple ? "" : node.Caption; }
            set { if (!multiple) { node.Caption = value; } }
        }

        public string Key
        {
            get { return multiple ? "" : node.Key; }
            set { if (!multiple) node.Key = value; }
        }

        public bool Enable
        {
            get { return multiple ? GetBoolValue("Enable") : node.Enable; }
            set { if (multiple) { SetValue("Enable", value); } else { node.Enable = value; } }
        }

        public string JavaPlugin
        {
            get { return multiple ? "" : (getJavaCode()!=null?"JavaPlugin":"NULL"); }
            set { }
        }

        public bool JavaEnable
        {
            get { bool result = true; if (java == null) java = getJavaCode();if (java != null) result = java.Enable;return result; }
            set { if (java == null) java = getJavaCode();if (java != null) java.Enable = value; }
        }

        public string TargetCaption
        {
            get { return multiple ? "" : node.TargetCaption; }
            set { if (multiple) SetValue("TargetCaption", value); else node.TargetCaption = value; }
        }

        public string TargetKey
        {
            get { return multiple ? "" : node.TargetKey; }
            set { if (multiple) SetValue("TargetKey", value); else node.TargetKey = value; }
        }
        /// <summary>
        /// 目标模块属性
        /// </summary>
        public BillModuleItem Target
        {
            get { return target; }
            set { target = value; }
        }

        public string RefectCaption
        {
            get { return multiple ? "" : node.RefectCaption; }
            set { if (multiple) SetValue("RefectCaption", value); else node.RefectCaption = value; } 
        }

        public string RefectKey
        {
            get { return multiple ? "" : node.RefectKey; }
            set { if (multiple) SetValue("RefectKey", value); else node.RefectKey = value; }
        }

        public string TriggerMode
        {
            get { return multiple ? "" : node.TriggerMode; }
            set { if (!multiple) node.TriggerMode = value; }
        }

        public string DataSource
        {
            get { return "[DataSource]"; }
            set { }
        }

        public string Formula
        {
            get { return multiple ? "" : node.Formula; }
            set { if (!multiple) node.Formula = value; }
        }

        public string FormulaCaption
        {
            get { return multiple ? "" : node.FormulaCaption; }
            set { if (!multiple) node.FormulaCaption = value; }
        }

        public string FormulaAlt
        {
            get { return "[Formula]"; }
            set { }
        }

        public BillRefectDataNodeOutList OutList
        {
            get { return multiple ? null : node.RefectValue; }
        }

        public BillRefectDataNodeWhereList WhereList
        {
            get { return multiple ? null : node.RefectWhere; }
        }

        public BillRefectDataNode DataNode
        {
            get { return multiple ? null : node; }
        }





        public bool IsMultiple()
        {
            return multiple;
        }

        public BillExpandJavaCodeItem getJavaCode()
        {
            BillExpandJavaCodeItem code = null;
            if (!multiple)
            {
                if (bill != null && bill.ExpandCode != null && bill.ExpandCode.JavaPlugin != null && bill.ExpandCode.JavaPlugin.JavaItem != null)
                {
                    foreach(BillExpandJavaCodeItem it in bill.ExpandCode.JavaPlugin.JavaItem)
                    {
                        if(it.Bind == node.Key)
                        {
                            code = it;
                            break;
                        }
                    }
                }
            }
            return code;
        }


        private object SetValue(string key, object value)
        {

            if (this.list != null && this.list.Length > 0)
            {
                for (int i = 0; i < this.list.Length; i++)
                {
                    BillReflectNodeToProperty data = list[i];
                    Type ClazzType = typeof(BillReflectNodeToProperty);
                    PropertyInfo Property = ClazzType.GetProperty(key);
                    if (Property != null)
                    {
                        Property.SetValue(data, value);
                    }
                }
            }
            return value;
        }

        private bool GetBoolValue(string key)
        {
            bool result = true;
            if (this.list != null && this.list.Length > 0)
            {
                for (int i = 0; i < this.list.Length; i++)
                {

                    BillReflectNodeToProperty data = list[i];
                    Type ClazzType = typeof(BillReflectNodeToProperty);
                    PropertyInfo Property = ClazzType.GetProperty(key);
                    if (Property != null && Property.GetMethod.ReturnType == typeof(bool))
                    {
                        object val = Property.GetValue(data);
                        if (val.Equals(false))
                        {
                            result = false;
                            break;
                        }
                    }
                }
            }

            return result;
        }

        private int GetIntValue(string key)
        {
            int result = 0;
            if (this.list != null && this.list.Length > 0)
            {
                BillReflectNodeToProperty data = list[0];
                Type ClazzType = typeof(BillReflectNodeToProperty);
                PropertyInfo Property = ClazzType.GetProperty(key);
                if (Property != null && Property.GetMethod.ReturnType == typeof(int))
                {
                    object val = Property.GetValue(data);
                    if (val is int)
                    {
                        result = (int)val;
                    }
                }
            }
            return result;
        }

        private string GetStringValue(string key)
        {
            string result = "";
            if (this.list != null && this.list.Length > 0)
            {
                for (int i = 0; i < this.list.Length; i++)
                {
                    BillReflectNodeToProperty data = list[i];
                    Type ClazzType = typeof(BillReflectNodeToProperty);
                    PropertyInfo Property = ClazzType.GetProperty(key);
                    if (Property != null && Property.GetMethod.ReturnType == typeof(string))
                    {
                        object val = Property.GetValue(data);
                        if (val is string)
                        {
                            if (result == "") result = val.ToString();
                            else if (result != (string)val)
                            {
                                result = "";
                                break;
                            }

                        }
                    }
                }
            }
            return result;
        }
    }
}
